﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.Models;

namespace testqwe
{
    //计算程序入口
    public class Program
    {
        private static int _length = 2000;
        public static void Start(Input input, int patternType, ref List<Output> outputs)
        {

            #region 参数设置
            var output = new Output();
            Constant.nomalLength = new List<int>();
            var ran = new Random();
            var length = (int)input.Length;
            _length = length;
            var width = (int)input.Width;
            Constant.BLK_NUM = input.Num;
            Constant.ROW = ran.Next(3, 4);
            var diameter = Array.ConvertAll(input.Diameter, d => (int)d);
            var value = input.Value;
            var b = input.Demand;
            var squer = input.Squer;
            #endregion


            var s = new GenSchema(length, width, diameter, b, value, patternType);//1为不对称，3无效，其它整数为对称
            //计时开始
            var dt1 = DateTime.Now;
            s.Generate_Schema();
            //计时结束
            var dt2 = DateTime.Now;
            var ts = dt2 - dt1;

            #region 将计算结果保存到计算结果模型(输出控制)
            output.Length = length;
            output.Width = width;
            output.Num = diameter.Length;
            output.Demand = b;
            output.Diameter = Array.ConvertAll(diameter, d => (double)d);

            output.Data += "length:  " + length + "  width:" + width + "\r\ndemand:  ";
            for (int x = 0; x < Constant.BLK_NUM; x++)
            {
                var str = s.B[x] + "   ";
                output.Data += str;
            }
            output.Data += "\r\ndiameter: ";
            for (int x = 0; x < Constant.BLK_NUM; x++)
            {
                var str = diameter[x] + "   ";
                output.Data += str;
            }
            var resultNum = s.xresult.Count;
            output.UtilizationRate = 0.0;
            output.TotalPlateNum = 0;
            output.PlateNum = new int[resultNum];
            PrintPattern prp = new PrintPattern();
            output.Plates = new List<List<List<int[]>>>();
            #region 循环每个排样

            for (int i = 0; i < resultNum; i++)
            {
                var n = (int)(s.xresult[i] + 0.9999);
                output.PlateNum[i] = n;
                output.TotalPlateNum += n;

                output.Plate = new List<List<int[]>>();
                prp.plate = new List<List<int[]>>();

                var div1 = s.result_pattern[i].divid;
                var div2 = s.result_pattern[i].dividright;
                if (div1 < 0 && div2 > 0)
                {
                    div1 = div2;
                    div2 = (int)(length - div1 - width / Math.Sqrt(3));
                }
                else if (div1 > 0 && div2 < 0)
                {
                    div2 = (int)(length - div1 - width / Math.Sqrt(3));
                }
                else if (div1 == 0 && div2 == 0)
                {
                    return;
                }

                prp.div1 = new[] { div1 };
                prp.div2 = new[] { div2 };
                prp.div = new List<int[]> { prp.div1, prp.div2, prp.plateNum };
                prp.tp = new List<int[]>();
                prp.pp = new List<int[]>();
                prp.tpForRight = new List<int[]>();
                var tp = s.result_pattern[i].tp;
                prp.tp = tp;
                var p = s.result_pattern[i].pp;
                prp.pp = p;
                var rp = s.result_pattern[i].tpForRight;
                prp.tpForRight = rp.Count > 0 ? rp : tp;
                rp = prp.tpForRight;
                var div = prp.div;
                prp.plate.Add(prp.tp);
                prp.plate.Add(prp.pp);
                prp.plate.Add(prp.tpForRight);
                prp.plate.Add(prp.div);

                //1
                output.Rectangles = new List<int[]>();
                //2
                output.Ellipses = new List<int[]>();
                //3
                output.Lines = new List<int[]>();
                //图形形状
                int type;
                //开始坐标（x,y）
                int xs;
                int ys;
                //大小（长宽，直线的话则是另一个点）
                int l;
                int w;
                //同一方向图形数量
                int num;
                //方向（横还是竖）
                int dir;


                type = 1;
                xs = 0;
                ys = 0;
                l = length;
                w = width;
                num = 1;
                dir = 1;

                var rectangle = new[] { type, xs, ys, l, w, num, dir };
                output.Rectangles.Add(rectangle);

                type = 3;
                xs = div[0][0];
                ys = 0;
                l = div[0][0] + (int)(width / Math.Sqrt(3));
                w = width;
                num = 1;
                dir = 1;
                var line = new[] { type, xs, ys, l, w, num, dir };
                output.Lines.Add(line);
                xs = div[1][0];
                l = div[1][0] + (int)(width / Math.Sqrt(3));
                line = new[] { type, xs, ys, l, w, num, dir };
                output.Lines.Add(line);


                int line1 = 0;//毛胚排列宽度
                for (int jj = 0; jj < tp.Count(); jj++)
                {//画左边梯形
                    int num2 = 0;//已画的毛胚数
                    int len;//每排毛胚个数
                    if (tp[jj][2] % tp[jj][1] == 0)
                        len = tp[jj][2] / tp[jj][1];
                    else
                        len = tp[jj][2] / tp[jj][1] + 1;

                    for (int j = 0; j < len; j++)
                    {
                        float x2 = j * diameter[tp[jj][0]];//毛胚列间隔

                        for (int k = 0; k < tp[jj][1]; k++)
                        {
                            float x = div[0][0] + width / 1.732f - line1 / 1.732f - x2 - diameter[tp[jj][0]] / 2 - 1.732f * diameter[tp[jj][0]] / 2 - k * diameter[tp[jj][0]] / 2;
                            float y = width - k * diameter[tp[jj][0]] / 2 * 1.732f - diameter[tp[jj][0]] - line1;//毛胚y坐标
                            float dia = diameter[tp[jj][0]];//毛胚半径


                            type = 2;
                            xs = (int)x;
                            ys = (int)y;
                            l = w = (int)dia;
                            num = 1;
                            dir = 1;
                            var ellipse = new[] { type, xs, ys, l, w, num, dir };
                            output.Ellipses.Add(ellipse);


                            num2++;
                            if (num2 == tp[jj][2])
                            {
                                break;
                            }

                        }


                    }
                    var yy1 = width - line1 - tp[jj][3];
                    var xx2 = div[0][0] + (float)(width / Math.Sqrt(3)) - (float)((line1 + tp[jj][3]) / Math.Sqrt(3));
                    var yy2 = width - line1 - tp[jj][3];

                    type = 3;
                    xs = 0;
                    ys = yy1;
                    l = (int)xx2;
                    w = yy2;
                    num = 1;
                    dir = 1;
                    line = new[] { type, xs, ys, l, w, num, dir };
                    output.Lines.Add(line);



                    line1 += tp[jj][3];
                }

                int line2 = 0;
                for (int jj = 0; jj < rp.Count(); jj++)
                {//画右边梯形
                    int num2 = 0;//已画毛胚数

                    int len;
                    if (rp[jj][2] % rp[jj][1] == 0)
                        len = rp[jj][2] / rp[jj][1];
                    else
                        len = rp[jj][2] / rp[jj][1] + 1;

                    for (int j = 0; j < len; j++)
                    {
                        float x2 = j * diameter[rp[jj][0]];

                        for (int k = 0; k < rp[jj][1]; k++)
                        {
                            var x = div[1][0] + x2 + line2 / 1.730f + (-diameter[rp[jj][0]] / 2 + 1.732f * diameter[rp[jj][0]] / 2) + k * diameter[rp[jj][0]] / 2;
                            float y = k * diameter[rp[jj][0]] / 2 * 1.732f + line2;//毛胚y坐标
                            float dia = diameter[rp[jj][0]];//毛胚半径

                            type = 2;
                            xs = (int)x;
                            ys = (int)y;
                            l = w = (int)dia;
                            num = 1;
                            dir = 1;
                            var ellipse = new[] { type, xs, ys, l, w, num, dir };
                            output.Ellipses.Add(ellipse);


                            num2++;

                            if (num2 == rp[jj][2])
                            {
                                break;
                            }

                        }

                        type = 3;
                        xs = (int)(div[1][0] + (float)((line2 + rp[jj][3]) / Math.Sqrt(3)));
                        ys = line2 + rp[jj][3];
                        l = length;
                        w = line2 + rp[jj][3];
                        num = 1;
                        dir = 1;
                        line = new[] { type, xs, ys, l, w, num, dir };
                        output.Lines.Add(line);

                    }
                    line2 += rp[jj][3];
                }

                float line3 = 0;
                int n3 = p.Count;
                for (int jj = 0; jj < n3; jj++)
                {
                    //画平行四边形

                    //TODO len1可能为0
                    float lineDiv = diameter[p[jj][0]];//画完一种毛胚之后所占宽度

                    //if (div[1][0]< div[0][0])
                    //{
                    //    //如果两条划分线中右边的小就交换位置
                    //    var temp = div[0][0];
                    //    div[0][0] = div[1][0];
                    //    div[1][0] = temp;
                    //}
                    int len1 = (div[1][0] - div[0][0]) / diameter[p[jj][0]];

                    if (len1 > p[jj][2])
                    {
                        len1 = p[jj][2];
                    }

                    int len2 = len1==0?0:p[jj][2] / len1;

                    for (int j = 0; j < len1; j++)
                    {

                        float x2 = j * diameter[p[jj][0]];

                        for (int k = 0; k < len2; k++)
                        {
                            float x = div[1][0] + (float)(width / Math.Sqrt(3)) - (line3 / 1.732f) - x2 - (diameter[p[jj][0]] / 2 + (float)(Math.Sqrt(3) * diameter[p[jj][0]] / 2)) - k * diameter[p[jj][0]] / 2;
                            float y = width - 2 * (diameter[p[jj][0]] / 2) - (float)(k * diameter[p[jj][0]] / 2 * Math.Sqrt(3)) - line3;
                            float dia = diameter[p[jj][0]];

                            type = 2;
                            xs = (int)x;
                            ys = (int)y;
                            l = w = (int)dia;
                            num = 1;
                            dir = 1;
                            var ellipse = new[] { type, xs, ys, l, w, num, dir };
                            output.Ellipses.Add(ellipse);
                            if (j == 0 && k >= 1)
                            {
                                lineDiv += 1.732f * diameter[p[jj][0]] / 2;
                            }


                        }



                    }
                    line3 += lineDiv;

                    type = 3;
                    xs = (int)(div[0][0] + (float)(width / Math.Sqrt(3)) - (line3) / 1.732f);
                    ys = (int)(width - line3);
                    l = (int)(div[1][0] + (float)(width / Math.Sqrt(3)) - (line3) / 1.732f);
                    w = (int)(width - line3);
                    num = 1;
                    dir = 1;
                    line = new[] { type, xs, ys, l, w, num, dir };
                    output.Lines.Add(line);
                }

                output.Plate.AddRange(new List<List<int[]>>
                        {
                            output.Ellipses,output.Lines,output.Rectangles

                        });

                output.Plates.Add(output.Plate);
            }
            output.DiaNum = s.presult;
            output.UtilizationRate = squer / length / width / output.TotalPlateNum;
            #endregion
            output.Result += length + ",,," + width + ",,," + Constant.ROW + ",,,算出消耗板材数=" + output.TotalPlateNum + "返回消耗板材数" + s.sheetnum + ",,利用率=" + output.UtilizationRate + "  avgtime=" + ts.TotalSeconds + "        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
            lock (output)
            {
                outputs.Add(output);
            }
            #endregion
        }

        //输出排样方式
        internal static void PrintPttern(Pattern pattern)
        {
            #region 每个排样数据存到输出模型中



            #endregion

            String str = "梯形排样1：";
            Console.WriteLine(str);
            List<int[]> tp = pattern.tp;
            int n = tp.Count;
            for (int i = 0; i < n; i++)
            {
                str = "毛坯编号:" + tp[i][0] + "   排数:" + tp[i][1] + "   毛坯个数:" + tp[i][2] + "   宽度：" + tp[i][3];
                Console.WriteLine(str);
            }
            str = "分割线1：" + pattern.divid;
            Console.WriteLine(str);
            str = "平行四边形排样：" + pattern.type;
            Console.WriteLine(str);
            List<int[]> pp = pattern.pp;
            int m = pp.Count;
            for (int i = 0; i < m; i++)
            {
                str = "毛坯编号:" + pp[i][0] + "   排数:" + pp[i][1] + "   毛坯个数:" + pp[i][2] + "   宽度：" + pp[i][3];
                Console.WriteLine(str);
            }
            if (pattern.dividright < 0)
            {
                pattern.dividright = _length + pattern.dividright;
            }
            str = "分割线1：" + pattern.dividright;
            Console.WriteLine(str);
            str = "梯形排样2：";
            Console.WriteLine(str);
            List<int[]> tr = pattern.tpForRight;
            int k = tr.Count;
            for (int i = 0; i < k; i++)
            {
                str = "毛坯编号:" + tr[i][0] + "   排数:" + tr[i][1] + "   毛坯个数:" + tr[i][2] + "   宽度：" + tr[i][3];
                Console.WriteLine(str);
            }
        }

        internal static void Write(String str)
        {
            //开始写入
            //sw.WriteLine(str);
            //清空缓冲区
            //sw.Flush();
        }
        internal static void Write(String str, int a)
        {
            //开始写入
            //sw.Write(str);
            //清空缓冲区
            //sw.Flush();
        }

    }
    /// <summary>
    /// 存放画图所需数据
    /// </summary>
    class PrintPattern
    {
        public int length;
        public int width;
        public int[] demand;
        public int[] diameter;
        public int[] plateNum;//板材数量
        public int[] totalNum;//每种排样中每种毛胚数量
        public List<int[]> tp;
        public List<int[]> pp;
        public List<int[]> tpForRight;
        public List<int[]> div;
        public int[] div1;
        public int[] div2;
        public string str;
        public string str2;
        public List<List<int[]>> plate;//排样方式的数据
        public List<List<List<int[]>>> plates;//排样的所有方式
        public static List<PrintPattern> pattern = new List<PrintPattern>();//排样的结果

    }
}
